package main

import (
	"fmt"
	"strings"
)

// 累加器
func AddUpper() func(int) int {
	// 从这一行到返回匿名函数 说明：
	// 返回的是一个匿名函数，但是这个匿名函数引用到函数外的n，因此这个匿名函数就和n形成一个整体，构成闭包
	//可以这样理解：闭包是类，函数时操作，n是字段，函数和她使用到的n构成闭包
	//当我们反复调用f函数时，因为n只初始化一次，因此每调用一次就进行累计
	//我们要搞清楚闭包的关键，就是分析出返回的函数它使用（引用）到哪些变量，因为函数和它引用到的变量共同构成闭包
	var n int = 10
	var str = "hello"
	return func(x int) int {
		n = n + x
		str += fmt.Sprintf("%d", x)
		fmt.Println("str=", str) // 1. str="hello$" 2. str="hello$$" 3. str="hello$$$"
		return n
	}
}

// 1)编写一个函数 makeSuffix(suffix string)  可以接收一个文件后缀名(比如.jpg)，并返回一个闭包
// 2)调用闭包，可以传入一个文件名，如果该文件名没有指定的后缀(比如.jpg) ,则返回 文件名.jpg , 如果已经有.jpg后缀，则返回原文件名。
// 3)要求使用闭包的方式完成
// 4)strings.HasSuffix , 该函数可以判断某个字符串是否有指定的后缀。
func makeSuffix(suffix string) func(string) string {
	return func(name string) string {
		//如果 name 没有指定后缀，则加上，否则就返回原来的名字
		if !strings.HasSuffix(name, suffix) {
			return name + suffix
		}

		return name
	}
}

func makeSuffix2(suffix string, name string) string {

	//如果 name 没有指定后缀，则加上，否则就返回原来的名字
	if !strings.HasSuffix(name, suffix) {
		return name + suffix
	}

	return name

}

// 闭包
func main() {

	//使用前面的代码
	f := AddUpper()
	fmt.Println(f(1)) //11
	fmt.Println(f(2)) //13

	//测试makeSuffix的使用
	//返回一个闭包
	f2 := makeSuffix(".jpg")               // 如果试用闭包完成，好处是只需要传入一次后缀
	fmt.Println("文件名处理后=", f2("winter"))   // winter.jpg
	fmt.Println("文件名处理后=", f2("bird.jpg")) // bird.jpg

	fmt.Println("文件名处理后=", makeSuffix2("jpg", "winter"))   // winter.jgp // 没用闭包就需要每次都写后缀名
	fmt.Println("文件名处理后=", makeSuffix2("jpg", "bird.jpg")) // bird.jpg
}
